<template>
	<view class="container">
		<view class="button wx-login">
			<u-button type="success" text="一键登陆"></u-button>
		</view>
		<view class="button phone-login" @tap="phoneLoginHandler">
			<u-button type="success" :plain="true" text="手机号登陆"></u-button>
		</view>
	</view>
</template>

<script setup lang="ts">
	import UButton from 'uview-ui/components/u-button/u-button.vue'
	import { ref, watch, toRefs } from 'vue';
	import request from '@/utils/request'
	import { WX_LOGIN } from '@/utils/request/api'
	import { useLoginStore } from '@/store/login'

  /**
   * TODO 免登陆逻辑：
   * 打开应用自动尝试调用code发起登陆，同时从storage中获取上传登陆的token
   * 如果token还在有效期内，则直接续期token并返回用户消息
   * 如果token未在有效期内，则尝试通过code获取token完成登陆流程（需检验用户是否注册，如果未注册则无法完成免登陆（缺少用户信息），返回失败）
  */
	
	
	const loginStore = useLoginStore()
	const { code, resetCode } = useCode()
	const { token, userInfo } = toRefs(loginStore)
	
	
	function phoneLoginHandler() {
		if (!code.value) {
			resetCode()
			return
		}
    uni.showToast({ icon: 'loading', title: '正在登陆', duration: 1000 * 30 })
		uni.getUserProfile({
			desc: "乱写一句话",
			success(res) {
				const { encryptedData, iv } = res
				request
					.post(WX_LOGIN, { code: code.value, encryptedData, iv })
					.then((reslutJson: any) => {
						uni.showToast({
							title: reslutJson.message
						})
            loginStore.login(reslutJson.data)
            // 如果页面数量大于1，说明存在上一页，则登陆成功后返回上一页。否则跳转到首页
            if (getCurrentPages().length > 1) {
              uni.navigateBack()
            } else {
              uni.reLaunch({ url: '/pages/index/index' })
            }
					})
          .catch(err => {
            uni.showToast({ icon: 'error', title: '登陆失败' })
          })
					
				resetCode()
			},
			fail(err) {
        uni.hideToast()
				console.log('getUserProfile fail', err)
			}
		})
	}

	defineExpose({
		phoneLoginHandler, token, userInfo
	})
	
	
	function useCode() {
		const code = ref('')
		
		let resetCodePromise = null
		let resetCodeTimer = null
		const resetCode = () => {
			if (resetCodePromise) return
			resetCodePromise = uni.login({
				success(res) {
					resetCodePromise = null
					code.value = res.code
					clearTimeout(resetCodeTimer)
					resetCodeTimer = setTimeout(() => {
						resetCode()
					}, 1000 * 60 * 5)
				},
				fail(err) {
					resetCodePromise = null
					console.log('login fail', err)
				}
			})
		}
		
		watch(code, (val) => {
			if (!val) {
				resetCode()
			}
		}, { immediate: true })
		
		return { code, resetCode }
	}
</script>

<style lang="scss">
	.container {
		height: 100vh;
		width: 100vw;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.button {
		margin: 20px;
	}

	.wx-login {
		width: 300rpx;
	}

	.phone-login {
		width: 300rpx;
	}
</style>